import style from './Spiders.module.scss';
import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  ExclamationCircleOutlined,
  FrownOutlined,
  PlusSquareOutlined,
} from '@ant-design/icons';
import {Button, Popover, Steps, Tag, Typography} from 'antd';
import React, {useEffect} from 'react';
import {
  AutoSizer,
  CellMeasurer,
  CellMeasurerCache,
  List,
} from 'react-virtualized';


const {Text} = Typography;
const {Step} = Steps;


const levelToColor = {
  INFO: '#878787',
  ERROR: '#ff4d4f',
  CRITICAL: '#ff4d4f',
  WARNING: '#faad14',
};
const levelToIcon = {
  INFO: null,
  ERROR: <CloseCircleOutlined/>,
  CRITICAL: <FrownOutlined/>,
  WARNING: <ExclamationCircleOutlined/>,
};
export const getOutputDescription = ({type, value}) => {
  switch (type) {
    case 'progress':
      return `已经爬取 ${value} 项`;
    case 'closed':
      return `爬取结束，退出原因为 ${value}`;
    case 'totalCount':
      return `搜索到 ${value} 条记录`;
    case 'parseError':
      return `页面解析错误，错误码为 ${value}`;
    case 'abandonISBN':
      return `无 ISBN，放弃 id ${value}`;
    case 'pageCount':
      return `爬取第 ${value.page} 页，` +
        `有 ${value.count} 条记录` +
          (value.notBook ? `，其中 ${value.notBook} 条不是图书`:'');
    case 'fail':
      if (value === 'parse error') {
        return `页面解析失败，退出`;
      } else if (value === 'proxy error') {
        return `获取代理失败，退出`;
      } else {
        return `失败并退出，原因：` + value;
      }
    case 'success':
      if (value === 'complete') {
        return `数据全部爬取完毕，退出`;
      } else if (value === 'max page') {
        return `达到限定的最大页数，退出`;
      } else {
        return `成功并退出，原因：` + value;
      }
    default:
      return `${type} = ${JSON.stringify(value)}`;
  }
};

const cache = new CellMeasurerCache({
  defaultHeight: 50,
  fixedWidth: true,
});

export const OutputDisplay = ({output}) => {
  useEffect(() => {
    cache.clearAll();
  }, [output]);

  const rowRenderer = ({
    index, // Index of row
    key, // Unique key within array of rendered rows
    parent, // Reference to the parent List (instance)
    style: pStyle, // Style object to be applied to row (to position it);
  }) => {
    const line = output[index];
    let content;
    if (line.unrecognized) {
      content = <div key={key}>
        <Tag
          className={style.head}>
          STDOUT
        </Tag>
        <Text code>
          {line.unrecognized}
        </Text>
      </div>;
    } else {
      content = <div key={key}>
        {
          line.parsedContent ?
            <Tag
              className={style.head}
              icon={<CheckCircleOutlined/>}
              color={'#1890ff'}>
              OUTPUT
            </Tag> :
            <Tag
              className={style.head}
              icon={levelToIcon[line.level]}
              color={levelToColor[line.level]}>
              {line.level}
            </Tag>
        }
        <Tag className={style.origin}>
          {line.origin}
        </Tag>
        <Text code className={style.content}>
          {line.parsedContent ?
            getOutputDescription(line.parsedContent) :
            line.content
          }
        </Text>
        {
          line.following && line.following.length !== 0 &&
          <Popover placement={'left'} trigger={'click'} content={<>
            {line.following.map((l, idx) => {
              return <Text key={idx} className={'following'} code>{l}</Text>;
            })}
          </>}>
            <Button size={'small'} type={'text'} icon={<PlusSquareOutlined/>}/>
          </Popover>
        }
        <Text code className={style.time}>{line.time}</Text>
      </div>;
    }

    return (
      <CellMeasurer
        cache={cache}
        columnIndex={0}
        rowIndex={index}
        key={key}
        parent={parent}
      >
        <div style={pStyle}
          className={style.line}
        >
          {content}
        </div>
      </CellMeasurer>
    );
  };

  return (<AutoSizer>
    {({height, width}) => {
      return <List
        height={height}
        width={width}
        overscanRowCount={10}
        rowCount={output.length}
        rowRenderer={rowRenderer}
        rowHeight={cache.rowHeight}
        deferredMeasurementCache={cache}
      />;
    }}
  </AutoSizer>);
};

export const getSteps = (item) => {
  const current = {
    queuing: 1,
    running: 2,
    finished: 3,
  };
  const statusMap = {
    queuing: 'process',
    running: 'process',
    finished: 'finish',
    failed: 'error',
    cancelled: 'error',
  };
  const status = item.status;
  let currentStep = current[status];
  if (status === 'failed' ||
    status === 'cancelled' ||
    status === 'cancelling') {
    currentStep = 1;
    if (item.started_at) {
      currentStep = 2;
    }
  }

  const runningDescription = item.started_at ?
    '运行于 ' + item.started_at : '';
  const percent = item.percent;
  const finishedDescription = item.finished_at ?
    '结束于 ' + item.finished_at : '';

  return <Steps
    percent={item.progress ? percent : undefined}
    status={statusMap[status]}
    direction="vertical"
    size="small" current={currentStep}
  >
    <Step title="创建" description={'创建于 ' + item.created_at}/>
    <Step title="排队"/>
    <Step title="运行"
      subTitle={item.progress ? percent + '%' : ''}
      description={runningDescription}/>
    <Step title="结束" description={finishedDescription}/>
  </Steps>;
};
